package com.mgface.metadata.design.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.mgface.metadata.design.dao.DataOperationMapper;
import com.mgface.metadata.design.datatypecheck.DataTypeValidation;
import com.mgface.metadata.design.dto.DataDTO;
import com.mgface.metadata.design.dto.FieldDTO;
import com.mgface.metadata.design.service.DataOperationService;
import com.mgface.metadata.design.utils.SnowFlakeUtil;
import com.mgface.metadata.design.vo.DataQueryVo;
import com.mgface.metadata.design.vo.DataVo;
import lombok.SneakyThrows;
import org.springframework.stereotype.Service;
import tk.mybatis.mapper.entity.Example;

import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;

/**
 * @author wanyuxiang
 * @version 1.0
 * @project mddesign
 * @create 2021-07-26 15:34
 **/
@SuppressWarnings("Duplicates")
@Service
public class DataOperationServiceImpl implements DataOperationService<DataDTO, DataVo> {
    private final DataOperationMapper dataOperationMapper;
    private final DataTypeValidation dataTypeValidation;

    public DataOperationServiceImpl(DataOperationMapper dataOperationMapper, DataTypeValidation dataTypeValidation) {
        this.dataOperationMapper = dataOperationMapper;
        this.dataTypeValidation = dataTypeValidation;
    }

    @SneakyThrows
    @SuppressWarnings("unchecked")
    @Override
    public String add(DataVo dataVo) {
        DataDTO dataDTO = new DataDTO();
        dataDTO.setGUID(SnowFlakeUtil.getId());
        dataDTO.setOrgID(dataVo.getOrgID());
        dataDTO.setAppID(dataVo.getAppID());
        dataDTO.setObjID(dataVo.getObjID());
        dataDTO.setName(dataVo.getDataName());

        Map<String, String> data = (Map<String, String>) JSONObject.parse(dataVo.getJsonData());

        //1.查询对象定义的字段
        List<FieldDTO> fields = dataOperationMapper.selectFieldsByOrgIDObjID(dataVo.getOrgID(), dataDTO.getObjID());
        //2.校验数据类型
        dataTypeValidation.dataTypeCheck(fields, data);
        //3.对DTO进行赋值操作
        fields.parallelStream().forEach(field -> {
            String val = data.get(field.getFieldName());
            if (val != null) {
                try {
                    Class cls = dataDTO.getClass();
                    Field f = cls.getDeclaredField(String.format("value%s", field.getFieldNum()));
                    f.setAccessible(true);
                    f.set(dataDTO, val);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        return dataOperationMapper.insert(dataDTO)== 1 ? dataVo.getGUID() : "insert error";
    }

    @Override
    public DataDTO get(DataQueryVo dataQueryVo) {
        Example example = new Example(DataDTO.class);
        example.createCriteria()
                .andEqualTo("orgID", dataQueryVo.getOrgID())
                .andEqualTo("appID", dataQueryVo.getAppID())
                .andEqualTo("GUID", dataQueryVo.getGUID());
        return dataOperationMapper.selectOneByExample(example);
    }

    @Override
    public int delete(DataQueryVo dataQueryVo) {
        Example example = new Example(DataDTO.class);
        example.createCriteria().andEqualTo("orgID", dataQueryVo.getOrgID())
                .andEqualTo("orgID", dataQueryVo.getOrgID())
                .andEqualTo("GUID", dataQueryVo.getGUID());
        return dataOperationMapper.deleteByExample(example);
    }

    @SneakyThrows
    @SuppressWarnings({"Duplicates", "unchecked"})
    @Override
    public int update(DataVo dataVo) {
        DataDTO dataDTO = new DataDTO();
        dataDTO.setName(dataVo.getDataName());

        Map<String, String> data = (Map<String, String>) JSONObject.parse(dataVo.getJsonData());

        //1.查询对象定义的字段
        List<FieldDTO> fields = dataOperationMapper.selectFieldsByOrgIDObjID(dataVo.getOrgID(), dataVo.getObjID());
        //2.校验数据类型
        dataTypeValidation.dataTypeCheck(fields, data);
        //3.对DTO进行赋值操作
        fields.parallelStream().forEach(field -> {
            String val = data.get(field.getFieldName());
            if (val != null) {
                try {
                    Class cls = dataDTO.getClass();
                    Field f = cls.getDeclaredField(String.format("value%s", field.getFieldNum()));
                    f.setAccessible(true);
                    f.set(dataDTO, val);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });


        Example example = new Example(DataDTO.class);
        example.createCriteria()
                .andEqualTo("GUID", dataVo.getGUID())
                .andEqualTo("orgID", dataVo.getOrgID())
                .andEqualTo("appID", dataVo.getAppID())
                .andEqualTo("objID", dataVo.getObjID());
        return dataOperationMapper.updateByExampleSelective(dataDTO, example);
    }

    @Override
    public List<DataDTO> getAll(String orgID, String objectID, String appID) {
        Example example = new Example(DataDTO.class);
        example.createCriteria().andEqualTo("orgID", orgID)
                .andEqualTo("objID", objectID)
                .andEqualTo("appID", appID);
        return dataOperationMapper.selectByExample(example);
    }
}
